package ai.people.platform.archives.ws.context;

import ai.people.core.security.entity.AuthenticationUser;
import ai.people.netmon.framework.exception.enums.AuthExceptionEnum;
import ai.people.netmon.framework.exception.type.AuthException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.security.core.Authentication;
import org.springframework.util.CollectionUtils;

import javax.websocket.Session;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author LiGuanNan
 * @date 2022/7/18 17:24
 */
@Slf4j
public class WsSessionContext {

    public static final List<Session> ALL_SESSIONS = new CopyOnWriteArrayList<>();
    /**
     * 维持会话，默认情况下websocket会话在一分钟内没有通信话会自动关闭，所以需要手动发送心跳来维持websocket的长连接
     * 服务端每30s主动向所有客户端发送一次websocket心跳消息
     */
    public static void keepAliveSessions(){
        if(CollectionUtils.isEmpty(ALL_SESSIONS)){
            return;
        }
        Iterator<Session> iterator = ALL_SESSIONS.iterator();
        while (iterator.hasNext()){
            Session session = iterator.next();
            if(!session.isOpen()){
                iterator.remove();
                continue;
            }
            try {
                AuthenticationUser authenticationUser = (AuthenticationUser) Optional.ofNullable((Authentication) session.getUserPrincipal()).map(Authentication::getPrincipal).orElseThrow(() -> new AuthException(AuthExceptionEnum.UNAUTHORIZED_ACCESS));
                log.info("服务端发送websocket心跳消息，保持websocket长连接, userId: {}, userName: {}", authenticationUser.getUserId(), authenticationUser.getUsername());
                session.getBasicRemote().sendText("heartbeat");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}
